######################################################################
# Reads EP binary data format, returns the data matrix
#
# The EP binary has (rows * cols + 2) elements. The first two elements
# are row and column numbers.
######################################################################
#BAD <- readBin ( "BadValuePDL.bin", "double", size = 4, n = 1 );

ep.readBin <- function ( con ) {
  library(Biobase)
  
  dims <- readBin ( con, "integer", size = 4, n = 2 );
  bindata <- readBin ( con, "double", size = 4, n = ( dims[1] * dims[2] + 2 ) );
  M <- matrix ( bindata [ 3 : ( dims[1] * dims[2] + 2 ) ], nrow = dims[1], byrow=T );

  # A BIT OF A HACK - PDL BAD VALUE is -3.402823e+38, but we need to get around floating point rounding, it seems.
  M [ round ( ( M - -3.402823e+38 ) * 10^-38 ) == 0 ] <- NA;

  if ( file.access(sub("\.bin.*",".rows",con), mode=0) == 0) {
    rowannots<-read.delim(file=sub("\.bin.*",".rows",con),quote="")
    if ( is.factor ( rowannots$CompositeSequence.identifier ) ) {
      v <- as.vector ( rowannots$CompositeSequence.identifier )
      v <- sub ( ".*:", "", v )
      rownames(M) <- v
    } else {
      rownames(M) <- rowannots[[2]]
    }
  }

  if ( file.access(sub("\.bin.*",".columns",con), mode=0) == 0) {
    colannots<-read.delim(file=sub("\.bin.*",".columns",con))
    colnames(M) <- colannots[[2]]
  }
  
  return ( M );
}

ep.writeBin <- function ( M, con ) {
  
  if ( class ( M ) == "exprSet" ) {
    M <- exprs(M)
  }

  zz<-file ( con, "wb" );
  writeBin(c(nrow(M),ncol(M)),zz, size=4);
  writeBin(as.vector(t(M)),zz, size=4);
  close(zz);
  
  zz <- file ( paste ( con, ".hdr", sep="" ), "wt" );
  cat ( "long\n0\n\nlong\n0\n\nfloat\n2\n", file=zz );
  cat ( paste ( ncol(M), nrow(M), sep=" " ), file=zz );
  cat ( "\n\n", file=zz );
  close ( zz );
}

ep.readBinExprSet <- function ( con ) {
  # read in matrix
  dims <- readBin ( con, "integer", size = 4, n = 2 );
  bindata <- readBin ( con, "double", size = 4, n = ( dims[1] * dims[2] + 2 ) );
  M <- matrix ( bindata [ 3 : ( dims[1] * dims[2] + 2 ) ], nrow = dims[1], byrow=T );

  # HACK - PDL BAD value is -3.402823e+38, but we need to get around floating point rounding, it seems
  M [ round ( ( M - -3.402823e+38 ) * 10^-38 ) == 0 ] <- NA;
  
  # read in phenoData
  cols <- read.delim ( file = sub ( "\.bin.*", ".columns", con ), quote="" );
  vlabels <- as.list(names(cols))
  names(vlabels) <- names(cols)

  rownames(cols) <- cols[[2]]
  pdata <- new ( "phenoData", pData = cols, varLabels = vlabels )

  # set row names ...
  colnames(M) <- cols[[2]]
  
  # ... and column names of the read-in matrix
  rows<-read.delim ( file = sub ( "\.bin.*", ".rows", con ) )
  rownames(M) <- rows[[2]]

  eset <- new( "exprSet", exprs = M, phenoData=pdata )
  return ( eset );
}
